/*//////////////////////////////////////////////////////////
 /// Demo of MVC implementation in javascript UI layer /////
 /// author - Alex Li //////////////////////////////////////
 //////////////////////////////////////////////////////////*/


/**
 **	Simple Data Grid View Class
 **	Events: 
 **		1). datagrid_render
 **		2). header_click
 **		3). cell_click
 **	
 **/
var SimpleDatagrid = Class.create();
SimpleDatagrid.prototype = Class.extend({
  /**
   **  Constructor
   **  Config JSON Spec:
   **  {
   **     container : <Type:HTML Element><Required:Y><Description:Where this view render to>
   **     width:<Type:Number><Required:N><Description:Width of grid>
   ** 	  controller : <Type: Controller Instance><Required:N><Description:controller to handle the events>
   **	  headers : <Type:JSon Array [{data_id:"xx",width:yyy,text:"ZZZ"}]><Required:Y><Description:Headers of the grid>
   **  }
   **/
  initialize: function(config){
      this.CurrentPage = 1;
      this.Headers = [];
      this.id = config.id?config.id:"";
      this.Headers = [];
      this.HeaderArray = new Array();
      this.Container = config.container;
      this.GridWidth = (config.width)?config.width:300;
      this.Controller = (config.controller)?config.controller:null;
      if(config.headers){
        this.SetHeaders(config.headers);
      } 
      if (config.model){
        this.Model = config.model;
      }else{
        this.Model = null;
      } 
      this.allocateProperty(config);
  },
  
  /**
   ** Config the header structure with config.headers
   **/
  SetHeaders:function(headers){
      for(i=0;i<headers.length;i++){
          this.Headers.push(headers[i].data_id);
          this.Headers[headers[i].data_id]={
                index:i,
                data_id:headers[i].data_id,
                text:headers[i].text,
                width:headers[i].width,
                title_align:headers[i].titlealign,
                data_align:headers[i].dataalign,
                inner_type:headers[i].innertype,
                column_inner_type:headers[i].columninnertype
          };
          this.HeaderArray[i] = this.Headers[headers[i].data_id];
      }
  },
  
  /**
   ** Render UI component to browser
   **/
  _Render:function(){
    this.DispathEvent("datagrid_render");
    var html ="<table style='background-color:#FFFFFF;padding-left:0px;'id='"+this.id+"_head' border='0' cellspacing='1' cellpadding='0' width='"+this.GridWidth+"'>";
		html +="<tr style='background-color: rgb(85, 85, 85); color: rgb(255, 255, 255);height:25px;overflow:hidden;'>";
		for(i=0;i<this.HeaderArray.length;i++){
			html += "<th id ='"+this.id+"_th_"+this.HeaderArray[i].data_id+"' align='left' style='text-align:left;cursor:pointer;overflow:hidden;'><div style='overflow:hidden;width:"+(Number(this.HeaderArray[i].width))+"px;'>&nbsp;" + this.HeaderArray[i].text +"</div></th>";
		}
		html +="</tr>";
			for(i=0;i<this.Model.RecordNumber;i++){
			  html += "<tr style='text-align:left;cursor:pointer;overflow:hidden;background-color:#F1F1F1;color:#000000;' id = '"+this.id+"tr_"+i+"'>";
		    for(j=0;j<this.HeaderArray.length;j++){
			 html += "<td id = '"+this.id+"td_"+this.HeaderArray[j].data_id+"_"+j+"'><div>"+this.Model.Get(i,this.HeaderArray[j].data_id)+"</div></td>";
		    }
		  html +="</tr>";
		}
		html +="</tbody></table>";
		return html;
  },
  
  /**
   ** Dispather of table header on click event
   **/
  On_header_click:function(evt){
  	this.DispathEvent("header_click",evt);
  },
  
  /**
   ** Dispather of table cell on click event
   **/
  On_cell_click:function(evt){
  	this.DispathEvent("cell_click",evt);
  },
  
  /**
   ** Dispather of table row mouse over
   **/
  On_mouse_over:function(evt) {
	this.DispathEvent("row_mouse_over",evt);
	var event = evt || window.event;
	var target = event.srcElement ? event.srcElement : event.target;
	var tr = target;
	while (tr) {
		if (tr.id && tr.id.indexOf("tr_") != -1) break;
		tr = tr.parentNode;
	}
	if (tr) {
		tr.style.backgroundColor = "rgb(177,216,237)";
	}
  },
  
  /**
   ** Dispather of table row mouse out
   **/
  On_mouse_out:function(evt) {
	this.DispathEvent("row_mouse_out",evt);
	var event = evt || window.event;
	var target = event.srcElement ? event.srcElement : event.target;
	var tr = target;
	while (tr) {
		if (tr.id && tr.id.indexOf("tr_") != -1) break;
		tr = tr.parentNode;
	}
	if (tr) {
		tr.style.backgroundColor = "#F1F1F1";
	}
  },
  
  /**
   ** Bind events for rows and headers
   **/
  _BindEvents:function(){
  	var ths = document.getElementById(this.id+"_head").getElementsByTagName("th");
  	for(i=0;i<ths.length;i++){
  		ths[i].onmousedown = this.On_header_click.bindAsEventListener(this);
  	}
  	var tds = document.getElementById(this.id+"_head").getElementsByTagName("tr");
  	for(i=0;i<tds.length;i++){
  		tds[i].onmousedown = this.On_cell_click.bindAsEventListener(this);
		tds[i].onmouseover = this.On_mouse_over.bindAsEventListener(this);
		tds[i].onmouseout = this.On_mouse_out.bindAsEventListener(this);
  	}
  },
  
  /**
   ** Get data index with column index number
   **/
  GetDataIndex:function(index) {
	return this.HeaderArray[index].data_id;
  }
},View.prototype);

/**
 **	Histogram chart view class
 **	Events: 
 **		1). histogram_render
 **	
 **/
var Histogram  = Class.create();
Histogram.prototype = Class.extend({
  /**
   **  Constructor
   **  Config JSON Spec:
   **  {
   **     container : <Type:HTML Element><Required:Y><Description:Where this view render to>
   **     x_text: <Type:String><Required:Y><Description:Caption of X axes>
   ** 	  y_text : <Type:String><Required:Y><Description:Caption of Y axes>
   **	  id : <Type:String><Required:Y><Description:ID of UI component>
   **     x_data_id : <Type:String><Required:Y><Description:Data index of X axes>
   **     y_data_id : <Type:String><Required:Y><Description:Data index of Y axes>
   **     controller : <Type: Controller Instance><Required:N><Description:controller to handle the events>
   **     model : <Type: Model Instance><Required:Y><Description:Data model>
   **  }
   **/
  initialize: function(config){
      this.X_data_id = config.x_data_id;
      this.Y_data_id = config.y_data_id;
      this.X_text = config.x_text;
      this.Y_text = config.y_text;
      this.Model = config.model;
      this.id = config.id;
      this.Container = config.container;
      this.height = config.height;
      this.cellspace = 100;
      this.Controller = (config.controller)?config.controller:null;
      this.allocateProperty(config);
	  this.colorBuilder = config.colorBuilder ? config.colorBuilder : null;
  },
  
  /**
   ** Render UI component to browser
   **/
  _Render:function(){
      this.DispathEvent("histogram_render");
	  this.Y_max = this._GetMaxY();
	  this.width = this.Model.RecordNumber * (this.cellspace + 10);
      var html = "<div id='"+this.id+"' style='width:"+this.width+"px;background-color: "+this._GetBackgroundColor()+"; color: rgb(255, 255, 255);height:"+this.height+"px;'>";
      html += "<div id='"+this.id+"_y' style='float:left;border-left:2px solid "+this._GetYAxisColor()+";position:relative;top:0px;left:10px;height:95%;width:35px;'>"+this.Y_text+"</div>";
      var chartHTML = "";
      for(i=0;i<this.Model.RecordNumber;i++){
		  var height = parseInt((this.Model.Get(i,this.Y_data_id)/this.Y_max)*100);
		  if (height < 3) height = "15px"; else height = height+"%";
          chartHTML += "<div style='font-size:11px;text-align:center;left:"+(i*this.cellspace)+";position:absolute;color: #000000;bottom:20px;height:"+height+";background-color:"+this._GetDataColor(this.Model.Get(i,this.Y_data_id))+";'>"+this.Model.Get(i,this.Y_data_id)+"</div>";
          chartHTML += "<div style='font-size:11px;left:"+(i*this.cellspace)+";position:absolute;bottom:0px;'>"+this.Model.Get(i,this.X_data_id)+"</div>";
      }
      html += "<div id='"+this.id+"_content' style='float:center;position:relative;top:0px;left:30px;height:"+(this.height-30)+"px;width:95%;'>"+chartHTML+"</div>";
      html += "<div id='"+this.id+"_x' style='float:bottom;border-top:2px solid "+this._GetXAxisColor()+";text-align:right;position:relative;top:0px;left:0px;height:30px;width:95%;'>"+this.X_text+"</div>";
      html += "</div>";
      return html;
  },
  
  /**
   ** Get max Y value from model
   **/
  _GetMaxY: function(){
	var max = 0;
	for(var i=0; i < this.Model.RecordNumber; i++) {
		var x = Number(this.Model.Get(i,this.Y_data_id))
		if (i==0 || max < x) {
			max = Number(x)
		}
	}
	return max + (max * 0.3);
  },
  
  ///////Color builder interface////////
  /////// Builder Pattern //////////////
  
  /**
   ** Get data rectangle color
   **/   
  _GetDataColor:function(data) {
	if (this.colorBuilder) {
		if (!this.colorBuilder.GetDataColor) {
			alert("Exception: Color builder interface method 'GetDataColor' doesn't been implemented!")
		} else {
			return this.colorBuilder.GetDataColor(data)
		}
	} else {
		return "rgb(0, 0, 0)";
	}
  },
  
  /**
   ** Get X Axis color
   **/   
  _GetXAxisColor:function() {
	if (this.colorBuilder) {
		if (!this.colorBuilder.GetXAxisColor) {
			alert("Exception: Color builder interface method '_GetXAxisColor' doesn't been implemented!")
		} else {
			return this.colorBuilder.GetXAxisColor();
		}
	} else {
		return "#FFFFFF";
	}
  },
  
  /**
   ** Get Y Axis color
   **/   
  _GetYAxisColor:function() {
	if (this.colorBuilder) {
		if (!this.colorBuilder.GetYAxisColor) {
			alert("Exception: Color builder interface method 'GetYAxisColor' doesn't been implemented!")
		} else {
			return this.colorBuilder.GetYAxisColor();
		}
	} else {
		return "#FFFFFF";
	}
  },
  
  /**
   ** Get background color
   **/   
  _GetBackgroundColor:function() {
	if (this.colorBuilder) {
		if (!this.colorBuilder.GetBackgroundColor) {
			alert("Exception: Color builder interface method 'GetBackgroundColor' doesn't been implemented!")
		} else {
			return this.colorBuilder.GetBackgroundColor();
		}
	} else {
		return "rgb(85, 85, 85)";
	}
  }
},View.prototype);
/**
 **	Field set view class
 **	Events: 
 **		1). fieldsset_render
 **	
 **/
var FieldsSet = Class.create();
FieldsSet.prototype = Class.extend({
  initialize: function(config){
       this.Fields = config.fields;//{data_id:"",label:"",type:"",values:[]}
       this.Model = config.model;
       this.KeyValue = (config.startkey)?config.startkey:0;
       this.id = config.id;
       this.Container = config.container;
       this.width = config.width;
       this.height = config.height;
       this.Footer = (config.footer)?config.footer:"";
       this.Controller = (config.controller)?config.controller:null;
	   this.Title = config.title ? config.title : 'Field Set';
       this.allocateProperty(config);
  },
  
  /**
   ** Render UI component to browser
   **/
  _Render:function(){
      this.DispathEvent("fieldsset_render");
      var html = "<div id='"+this.id+"' style='width:"+this.width+"px;background-color: rgb(200,200,200); color: rgb(255, 255, 255);height:"+this.height+"px;'><fieldset style='margin-left:2px;color:rgb(99,99,99);border:rgb(99,99,99) solid 1px;height:"+(this.height-25)+"px;width :"+(this.width-30)+"px;'><legend>"+ this.Title +"</legend>";
      html += "<table style='padding-left:3px;'id='"+this.id+"_frame' border='0' cellspacing='1' cellpadding='0' width='100%' height='100%'>";
      html += "<tbody>";
      for (i=0;i<this.Fields.length;i++){
        html += "<tr>";
        html += "<td style='width:30%;'>"+this.Fields[i].label+"</td>";
        html += "<td>"+this._TypeFactory(this.Fields[i],this.Model.Get(this.KeyValue,this.Fields[i].data_id))+"</td>";
        html += "</tr>";
      }
      html+="<tr><td colspan='2'>"+this.Footer+"</td></tr>";
	  html+="<tr><td colspan='2' style='height:100%;'></td></tr>";
      html += "</tbody></table></fieldset>";
      html += "</div>";
	  return html;
  },
  
  /**
   ** HTML Factory for different field types
   **/
  _TypeFactory:function(field,data){
     var html = "";
     switch (field.type){
        case "input":
          html = "<input id= '"+field.data_id+"' style='width:80%;height:23px;' value='"+data+"'/>";
        break;
        case "dropdown":
          html = "<select id='"+field.data_id+"' style='width:80%;height:23px;'>";
          for (i=0;i<field.values.length;i++){
            var checked = "";
            if(field.values[i]==data) checked = "selected = 'selected'";
            html+= "<option value='"+field.values[i]+"' "+checked+">"+field.values[i]+"</option>";
          }
          html += "</select>";
        break;
        case "div":
        default:
          html = "<div>"+data+"</div>";
        break;
     }
     return html;
  }
},View.prototype);

/**
 ** Tab View
 **/
var TabView = Class.create();
TabView.prototype = Class.extend({
	  /**
	   **  Constructor
	   **/
	  initialize: function(config){
		 this.Tabs = config.tabs ? config.tabs : [{TabText:'Tab 1', View:null, width:50, Html:''}];
		 this.CurrentTab = 1;
		 this.Container = config.container;
		 this.height = config.height ?  config.height : 300;
		 this.width = config.width ? config.width : 400;
		 this.allocateProperty(config);
	  },
	  
	  /**
	   ** Render UI component to browser
	   **/
	  _Render:function(){
		  var html = "<div id='" + this.id + "_tab_view' style='background-color:rgb(200,200,200);width:"+this.width+"px;height:"+this.height+"px;'><table id='" + this.id + "_tab_header'><tr>";
		  var content = this._GetContent();
		  var tabWidthTotal = 0;
		  for (var i=0; i<this.Tabs.length;i++) {
			var selectedColor = "rgb(99,99,99)";
			if (i == (this.CurrentTab-1)) {
				selectedColor = "rgb(135,135,135)"; 
			}
			html += "<td id='" + this.id + "_tab_"+i+"' style='cursor:pointer;background-color:"+selectedColor+";width:"+this.Tabs[i].width+"px;'>"+this.Tabs[i].TabText+"</td>";
			tabWidthTotal += this.Tabs[i].width;
		  }
		  html += "<td style='width:"+(this.width - tabWidthTotal)+"px'></td>";
		  html += "</tr><tr><td colspan='"+(this.Tabs.length+1)+"'><div id='"+this.id+"_content' style='width:"+this.width+"px;height:"+this.height+"px;'>"+content+"</div></td></tr>";
		  html += "</table>"; 
		  html += "</div>";
		  return html;
	  },
	  
	  /**
	   ** Bind Events
	   **/
	  _BindEvents:function(){
		  var self =this;
		  for (var i=0;i<this.Tabs.length;i++) {
			var tabElement = document.getElementById(this.id+"_tab_"+i);
			if (tabElement) {
				tabElement.onclick = function(evt) {
					var event = evt || window.event;
					var target = event.srcElement ? event.srcElement : event.target;
					var tabId = target.id.split("_")[2];
					var context = new Object();
					context.tabId = tabId;
					self.NotifyObserver("ON_TAB_SELECTED",context);
					self.SetContent(Number(tabId));
				}
			}
		  }
		  var content = document.getElementById(this.id+"_content");
		  if (this.Tabs[this.CurrentTab-1].View && this.Tabs[this.CurrentTab-1].View.BindEvents) {
		    this.Tabs[this.CurrentTab-1].View.Container = content;
			this.Tabs[this.CurrentTab-1].View.BindEvents();
		  }
	  },
	  
	  /**
	   ** Set Page content by specifying index
	   **/
	  SetContent:function(index){
		var tab = document.getElementById(this.id+"_tab_"+(this.CurrentTab-1));
		tab.style.backgroundColor = "rgb(99,99,99)";
		var content = document.getElementById(this.id+"_content");
		this.CurrentTab = index+1;
		var innerHTML = this._GetContent();
		content.innerHTML = innerHTML;
		tab = document.getElementById(this.id+"_tab_"+(this.CurrentTab-1));
		tab.style.backgroundColor = "rgb(135,135,135)";
		if (this.Tabs[this.CurrentTab-1].View && this.Tabs[this.CurrentTab-1].View.BindEvents) {
			this.Tabs[this.CurrentTab-1].View.Container = content;
			this.Tabs[this.CurrentTab-1].View.BindEvents();
		}
	  },
	  
	  /**
	   ** Get Content Inner HTML
	   **/
	  _GetContent : function() {
		var content = '';
		if (this.Tabs[this.CurrentTab-1].Html) {
			content = this.Tabs[this.CurrentTab-1].Html;
		} else if (this.Tabs[this.CurrentTab-1].View) {
			content = this.Tabs[this.CurrentTab-1].View._Render();
		}
		return content;
	  }
},View.prototype);

/**
 ** Scroll Decorator
 **/
var ScrollFrame = Class.create();
ScrollFrame.prototype = Class.extend({
	/**
	 ** Initialize additional config options
	 **/
	preCreateObject:function () {
		if (this.config.width) {
			this.width = this.config.width;
		} else {
			this.width = 300;
		}
		if (this.config.height) {
			this.height = this.config.height;
		} else {
			this.height = 300;
		}
	},
	
	/**
	 ** Decorate view
	 **/
	_Render: function (response) {
		var html = "<div style='overflow:auto;width:" + this.width + "px;height:" + this.height + "px;'>"
				  + this.view._Render(response) + "</div>";	
		return html;
	}
},Decorator.prototype);

/**
 ** Window frame Decorator
 ** Events: PRE_CLOSE
 ** 		POST_CLOSE
 **/
var WindowFrame = Class.create();
WindowFrame.prototype = Class.extend({
	/**
	 ** Initialize additional config options
	 **/
	preCreateObject:function () {
		this.initialized = false;
		if (this.config.width) {
			this.width = this.config.width;
		} else {
			this.width = 300;
		}
		if (this.config.height) {
			this.height = this.config.height;
		} else {
			this.height = 300;
		}
		if (this.config.title) {
			this.title = this.config.title;
		} else {
			this.title = "New Window";
		}
		if (this.config.X) {
			this.X = this.config.X;
		} else {
			this.X = 0;
		}
		if (this.config.Y) {
			this.Y = this.config.Y;
		} else {
			this.Y = 0;
		}
	},
	
	/**
	 ** Decorate view
	 **/
	_Render: function (response) {
		var html = "<table unselectable='on' cellpadding='0' cellspace='0' frame='box' style='background-color:#FFFFFF;-moz-user-select: none;-khtml-user-select: none;user-select: none;'>"
				  + "<tr style='height:35px;background-color:#000068;'><td>"
				  + "<table id='" + this.id + "_title' style='color:#FFFFFF;cursor:move;' width='100%'><tr><td style='width:100%;'>" + this.title + "</td><td align='right' style='width:20px;'><span id='" + this.id + "_close' style='cursor:pointer;'>[x]</span></td></tr>"
				  + "</table></td></tr>"
				  + "<tr><td>" + this.view._Render(response) + "</td></tr></table>";	
		return html;
	},
	
	/**
	 ** Display the window
	 **/
	Show:function(){
		this.Container.style.display = '';
	},
	
	/**
	 ** Close the window
	 **/
	Close:function(){
		this.Container.style.display = 'none';
	},
	/**
	 ** Bind events
	 **/
	_BindEvents:function(){
		/**
		 ** Drag & Drop event
		 **/
		if (!this.initialized) {
			this.Container.style.position = "absolute";
			this.Container.style.top = this.Y + "px";
			this.Container.style.left = this.X + "px";
			this.Container.style.zIndex = "8888";
			this.initialized = true;
		}
		var self = this;
		var titleSection = document.getElementById(this.id + "_title");
		if (titleSection) {
			titleSection.onmousedown = function(evt) {
				if (!document.getElementById("divCover")) {
					var event = evt || window.event;
					var target = event.srcElement ? event.srcElement : event.target;
					if (target.id == self.id + "_close") return;
					self.mouseX = Number(event.screenX);
					self.mouseY = Number(event.screenY);
					self.X = self.Container.style.left.replace("px","");
					self.Y = self.Container.style.top.replace("px","");
					var divCover = document.createElement("div");
					divCover.id = "divCover";
					divCover.style.position = "absolute";
					divCover.style.top = "0px";
					divCover.style.left = "0px";
					divCover.style.width = document.body.offsetWidth + "px";
					divCover.style.height = document.body.offsetHeight + "px";
					divCover.style.zIndex = "9999";
					divCover.style.cursor = "move";
					document.body.appendChild(divCover);
					divCover.onmouseup = function(evt) {
						document.body.removeChild(divCover);
					}
					
					divCover.onmousemove = function(evt) {
						var event = evt || window.event;
						self.Container.style.position = "absolute";
						self.X = Number(self.X) + (Number(event.screenX) - Number(self.mouseX));
						self.Y = Number(self.Y) + (Number(event.screenY) - Number(self.mouseY));
						self.Container.style.top = self.Y + "px";
						self.Container.style.left = self.X + "px";
						self.mouseX = Number(event.screenX);
						self.mouseY = Number(event.screenY);
					}
					
					divCover.onmouseout = function(evt) {
						document.body.removeChild(divCover);
					}
				}
			}
		}
		/**
		 ** Close event
		 **/
		var closeBttn = document.getElementById(this.id + "_close"); 
		if (closeBttn) {
			closeBttn.onmousedown = function(evt) {
				var event = evt || window.event;
				var context = new Object();
				context.Event = event;
				context.ViewObj = self;
				self.NotifyObserver("PRE_CLOSE",context);
				if(!context.StopEvent) {
					self.Close();
					self.NotifyObserver("POST_CLOSE",context);
				}
			}
		}
	}
},Decorator.prototype);


/**
 **	Layout Compositer View
 **	Events: 
 **		1). layout_render
 **		2). bind_events
 **/
var Layout = Class.create();
Layout.STYLE_VERTICAL = "vertical";
Layout.STYLE_HORIZONTAL = "horizontal"; 
Layout.prototype = Class.extend({
  /**
   **  Constructor
   **  Config JSON Spec:
   **  {
   **     container : <Type:HTML Element><Required:Y><Description:Where this view render to>
   **     layoutStyle: <Type:boolean><Description:Style of layout - vertical or horizontal>
   **     cells:<Type:JSON Array><Description:Cell meta data> {view:X,width:Y,height:Z,html:S}
   **     showBorder: <Type:boolean><Description:Set if the border will display on view>
   **  }
   **/
  initialize: function(config){
    this.layoutStyle = config.layoutStyle ? config.layoutStyle : Layout.STYLE_VERTICAL;
	this.cells = config.cells ? config.cells : new Array();
	this.cellCount = this.cells.length;
	this.Container = config.container;
	if (this.Container) this.isCell = false; else this.isCell = true;
	this.showBorder = !config.showBorder ? false : true;
	this.allocateProperty(config);
  },
  
  /**
   ** Add new view into compositer
   **/
  Add:function(view) {
	this.views[this.views.length-1] = view;
	this.cellCount = this.cells.length;
  },
  
  /**
   ** Bind events
   **/
  _BindEvents: function() {
	for(var i=0; i<this.cells.length;i++) {
		if (!this.cells[i].view) continue;
		this.cells[i].view.Container = document.getElementById(this.id+"_cell_"+i);
		this.cells[i].view.BindEvents();
	}	
  },
  
  /**
   ** Render View
   **/
  _Render: function(){
	if (this.layoutStyle == Layout.STYLE_VERTICAL) {
		return this._drawVertical();
	} else {
		return this._drawHorizontal();
	}
  },
  
  /**
   ** Generate vertial layout html
   **/
  _drawVertical : function(){
	var verticalBorderWidth = this.showBorder ? 5 : 0;
	var horizontalBorderHeight = this.showBorder ? 5 : 0;
	var borderColor = "rgb(49,73,106)";
	var html = "<table id='"+this.id+"_layout_table' cellspacing='0' cellpadding='0' border='0'>";
	if (!this.isCell)html += "<tr class='layout_horizontal_border' style='height:"+horizontalBorderHeight+"px;background-color:"+borderColor+";cursor:n-resize;'><td></td></tr>";
	for (var i=0; i<this.cells.length;i++) {
		var tdHeight = this.cells[i].height ? "height:" + this.cells[i].height + ";": '';
		var tdWidth = this.cells[i].width ? "width:" + this.cells[i].width + ";": '';
		html +="<tr><td id='"+this.id+"_cell_"+i+"' valign='top' style='"+tdHeight+tdWidth+"'>";
		html += this.cells[i].view._Render();
		html +="</td></tr>";
		if (i==this.cells.length-1) continue;
		html +="<tr class='layout_horizontal_border' style='height:"+horizontalBorderHeight+"px;background-color:"+borderColor+";cursor:n-resize;'><td></td></tr>";
	}
	if (!this.isCell)html += "<tr class='layout_horizontal_border' style='height:"+horizontalBorderHeight+"px;background-color:"+borderColor+";cursor:n-resize;'><td></td></tr>";
	html += "</table>";
	if (!this.isCell)html = "<table cellspacing='0' cellpadding='0' border='0'><tr><td class='layout_vertical_border_left' style='width:"+verticalBorderWidth+"px;background-color:"+borderColor+";cursor:e-resize;'></td><td>"+html+"</td><td class='layout_vertical_border_right' style='width:"+verticalBorderWidth+"px;background-color:"+borderColor+";cursor:e-resize;'></td></tr></table>";
	
	return html;
  },
  
  /**
   ** Generate horizontal layout html
   **/
  _drawHorizontal: function(){
	var verticalBorderWidth = this.showBorder ? 5 : 0;
	var horizontalBorderHeight = this.showBorder ? 5 : 0;
	var borderColor = "rgb(49,73,106)";
	var html = "<table id='"+this.id+"_layout_table' cellspacing='0' cellpadding='0' border='0'>";
	html += "<tr class='layout_horizontal_border' style='height:"+horizontalBorderHeight+"px;background-color:"+borderColor+";cursor:n-resize;'><td colspan='"+(this.cells.length*2-1)+"'></td></tr>";
	html += "<tr>";
	for (var i=0; i<this.cells.length;i++) {
		var tdHeight = this.cells[i].height ? "height:" + this.cells[i].height + ";": '';
		var tdWidth = this.cells[i].width ? "width:" + this.cells[i].width + ";": '';
		html +="<td id='"+this.id+"_cell_"+i+"' valign='top' style='"+tdHeight+tdWidth+"'>";
		html += this.cells[i].view._Render();
		html +="</td>";
		if (i==this.cells.length-1) continue;
		html +="<td class='layout_vertical_border_left'' style='width:"+verticalBorderWidth+"px;background-color:"+borderColor+";cursor:e-resize;'></td>";
	}
	html += "</tr>";
	html += "<tr class='layout_horizontal_border' style='height:"+horizontalBorderHeight+"px;background-color:"+borderColor+";cursor:n-resize;'><td colspan='"+(this.cells.length*2-1)+"'></td></tr>";
	html += "</table>";
	html = "<table cellspacing='0' cellpadding='0' border='0'><tr><td class='layout_vertical_border_left' style='width:"+verticalBorderWidth+"px;background-color:"+borderColor+";cursor:e-resize;'></td><td>"+html+"</td><td class='layout_vertical_border_right' style='width:"+verticalBorderWidth+"px;background-color:"+borderColor+";cursor:e-resize;'></td></tr></table>";
	
	return html;
  }
},View.prototype);